﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TA.DotNetUtils;

/// <summary>
/// Used behind the scenes to provide dual access to a list of string values: by reading and writing a single string which consists of comma-separated individual values, or by adding and removing individual values from a List&lt;string&gt; instance.
/// </summary>
public class MultiPartValue : BaseMultiPartValue<string>
{
	#region STATIC
	/// <summary>
	/// Adds the specified value to the specified collection, using the specified InclusionMode.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="mode"></param>
	/// <param name="list"></param>
	/// <param name="value"></param>
	public static void AddValue<T>(InclusionMode mode, List<T> list, T value)
	{
		if (mode == InclusionMode.OnlyIncluded)
		{
			foreach (T t in list)
			{
				if (object.Equals(t, value)) return;
			}
			list.Add(value);
		}
		else
		{
			foreach (T t in list)
			{
				if (object.Equals(t, value))
				{
					list.Remove(t);
					return;
				}
			}
		}
	}
	/// <summary>
	/// Removes the specified value from the specified collection, using the specified InclusionMode.
	/// </summary>
	public static void RemoveValue<T>(InclusionMode mode, List<T> list, T value)
	{
		if (mode == InclusionMode.OnlyIncluded)
		{
			foreach (T t in list)
			{
				if (object.Equals(t, value))
				{
					list.Remove(t);
					return;
				}

			}
		}
		else
		{
			foreach (T t in list)
			{
				if (object.Equals(t, value))
					return;
			}
			list.Add(value);
		}
	}
	/// <summary>
	/// Checks if the specified value is included in the specified collection, using the specified InclusionMode.
	/// </summary>
	public static bool IsIncluded<T>(InclusionMode mode, IEnumerable<T> list, T value)
	{
		foreach (T t in list)
			if (object.Equals(t, value))
				return mode == InclusionMode.OnlyIncluded;
		return mode == InclusionMode.AllExceptExcluded;
	}
	/// <summary>
	/// Gets the list of all applicable items by using the specified mode, list and complete list.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="mode"></param>
	/// <param name="list"></param>
	/// <param name="completeList"></param>
	/// <returns></returns>
	public static IEnumerable<T> GetActiveList<T>(InclusionMode mode, IEnumerable<T> list, IEnumerable<T> completeList)
	{
		List<T> res = new List<T>();
		if (mode == InclusionMode.OnlyIncluded)
			res.AddRange(list);
		else
		{
			foreach (T t1 in completeList)
			{
				bool good = true;
				foreach (T t2 in list)
				{
					if (object.Equals(t1, t2))
					{
						good = false;
						break;
					}
				}
				if (good)
					res.Add(t1);
			}
		}
		return res;
	}
	#endregion
	#region PUBLIC
	#region INIT
	/// <summary>
	/// Ctor.
	/// </summary>
	public MultiPartValue()
	{
	}
	#endregion
	#endregion
	#region INTERNAL
	#region METHODS
	/// <summary>
	/// Gets the array of values from the specified comma-separated list of values.
	/// </summary>
	/// <param name="value"></param>
	/// <returns></returns>
	protected override string[] GetValueList(string value)
	{
		return (value ?? "").Split(Separators, StringSplitOptions.RemoveEmptyEntries);
	}
	/// <summary>
	/// Gets the comma-separated list of values from the specified array of values.
	/// </summary>
	/// <param name="valueList"></param>
	/// <returns></returns>
	protected override string GetValue(List<string> valueList)
	{
		return string.Join(",", valueList.ToArray());
	}
	#endregion
	#endregion
}
